home *** CD-ROM | disk | FTP | other *** search
- /*
- * (c) Copyright 1992 by Panagiotis Tsirigotis
- * All rights reserved. The file named COPYRIGHT specifies the terms
- * and conditions for redistribution.
- */
-
- static char RCSid[] = "$Id: retry.c,v 5.2 1992/11/10 08:18:25 panos Exp $" ;
-
- #include <sys/time.h>
- #include <syslog.h>
-
- #include "pset.h"
-
- #include "access.h"
- #include "config.h"
- #include "server.h"
- #include "state.h"
- #include "connection.h"
-
- void msg() ;
- void out_of_memory() ;
-
- static psi_h iter ;
- static bool_int retry_timer_running ;
-
-
- /*
- * Attempt to start all servers in the retry table
- */
- void server_retry()
- {
- register struct server *retry_serp ;
- unsigned servers_started = 0 ;
- char *func = "server_restart" ;
- void cancel_retry() ;
- void stop_retry_timer() ;
- void log_failure() ;
-
- if ( iter == NULL )
- {
- iter = psi_create( ps.rws.retries ) ;
- if ( iter == NULL )
- {
- out_of_memory( func ) ;
- return ;
- }
- }
-
- for ( retry_serp = SERP( psi_start( iter ) ) ; retry_serp != NULL ;
- retry_serp = SERP( psi_next( iter ) ) )
- {
- register struct service *sp = SERVER_SERVICE( retry_serp ) ;
- connection_s *cp = SERVER_CONNECTION( retry_serp ) ;
-
- /*
- * Drop the retry if access control fails or we have
- * a memory allocation problem
- */
- if ( svc_access_control( sp, cp ) == FAILED ||
- pset_add( ps.rws.servers, retry_serp ) == NULL )
- {
- cancel_retry( retry_serp ) ;
- psi_remove( iter ) ;
- continue ;
- }
-
- if ( server_start( retry_serp ) == OK )
- {
- servers_started++ ;
- SDATA( sp )->retry_servers-- ;
- psi_remove( iter ) ;
- continue ;
- }
- else
- {
- pset_remove( ps.rws.servers, retry_serp ) ;
- if ( retry_serp->fork_failures >= MAX_FORK_FAILURES )
- {
- /*
- * give up retrying
- */
- msg( LOG_ERR, func, "service %s: %d consecutive fork failures",
- CONF( sp )->id, retry_serp->fork_failures ) ;
- log_failure( AC_FORK, sp, cp ) ;
- cancel_retry( retry_serp ) ;
- psi_remove( iter ) ;
- continue ;
- }
- else
- {
- if ( debug.on )
- msg( LOG_DEBUG, func,
- "fork failed for service %s. Retrying...", CONF( sp )->id ) ;
- }
- }
- }
-
- if ( debug.on )
- msg( LOG_DEBUG, func,
- "%d servers started, %d left to retry",
- servers_started, pset_count( ps.rws.retries ) ) ;
-
- if ( pset_count( ps.rws.retries ) == 0 )
- stop_retry_timer() ;
- }
-
-
- /*
- * Schedule a retry by inserting the struct server in the retry table
- * and starting the timer if necessary
- */
- status_e schedule_retry( serp )
- struct server *serp ;
- {
- void start_retry_timer() ;
- char *func = "schedule_retry" ;
-
- if ( pset_add( ps.rws.retries, serp ) == NULL )
- {
- out_of_memory( func ) ;
- return( FAILED ) ;
- }
- SVC_HOLD( SERVER_SERVICE( serp ) ) ;
- SDATA( SERVER_SERVICE( serp ) )->retry_servers++ ;
- start_retry_timer() ;
- return( OK ) ;
- }
-
-
- /*
- * This function should not be called for servers that correspond to
- * services not in the service table because server_release will result
- * in releasing all memory associated with the service (since the ref
- * count will drop to 0).
- */
- void cancel_retry( serp )
- struct server *serp ;
- {
- struct service *sp = SERVER_SERVICE( serp ) ;
-
- conn_free( SERVER_CONNECTION( serp ) ) ;
- SDATA( sp )->retry_servers-- ;
- server_release( serp ) ;
- }
-
-
-
- /*
- * Cancel all retry attempts for the specified service
- */
- void cancel_service_retries( sp )
- register struct service *sp ;
- {
- register unsigned u ;
- char *func = "cancel_service_retries" ;
-
- if ( SDATA( sp )->retry_servers == 0 )
- return ;
-
- u = 0 ;
- while ( u < pset_count( ps.rws.retries ) )
- {
- register struct server *serp ;
-
- serp = SERP( pset_pointer( ps.rws.retries, u ) ) ;
- if ( SERVER_SERVICE( serp ) == sp )
- {
- msg( LOG_NOTICE, func,
- "dropping retry attempt for service %s", CONF( sp )->id ) ;
- cancel_retry( serp ) ;
- pset_remove_index( ps.rws.retries, u ) ;
- continue ;
- }
- u++ ;
- }
- }
-
-
- PRIVATE void start_retry_timer()
- {
- /*
- * The retry itimerval is set so that the timer expires every 1 second
- * when it is enabled.
- */
- static struct itimerval itv =
- {
- { RETRY_INTERVAL, 0 },
- { RETRY_INTERVAL, 0 }
- } ;
-
- /*
- * Enable timer if necessary.
- */
- if ( ! retry_timer_running )
- if ( setitimer( ITIMER_REAL, &itv, ITIMERVAL_NULL ) == -1 )
- msg( LOG_ERR, "start_retry_timer", "setitimer: %m" ) ;
- else
- retry_timer_running = TRUE ;
- }
-
-
- PRIVATE void stop_retry_timer()
- {
- if ( retry_timer_running )
- {
- (void) setitimer( ITIMER_REAL, ITIMERVAL_NULL, ITIMERVAL_NULL ) ;
- retry_timer_running = FALSE ;
- }
- }
-
-